package net.hserver.gateway.service.impl;

import top.hserver.core.ioc.annotation.Autowired;
import top.hserver.core.ioc.annotation.Bean;
import net.hserver.gateway.config.StrategyType;
import net.hserver.gateway.core.node.Manager;
import net.hserver.gateway.core.strategy.ServerNode;
import net.hserver.gateway.dto.GatewayRouterNodeDTO;
import net.hserver.gateway.service.GatewayRouterService;
import net.hserver.gateway.service.ServerService;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hxm
 */
@Bean
public class ServerServiceImpl implements ServerService {

    @Autowired
    private Manager manager;

    @Autowired
    private GatewayRouterService gatewayRouterService;

    private void addServer(GatewayRouterNodeDTO node) {
        try {
            ServerNode serverNode = new ServerNode();
            //连接数
            serverNode.setConnectNum(0L);
            //url
            serverNode.setUrl(node.getUrl());
            //路由ID
            serverNode.setRouterId(node.getRouterId());
            //匹配规则URl
            serverNode.setNodeId(node.getNodeId());
            //节点类型
            serverNode.setType(node.getType());
            //ip port
            InetSocketAddress inetSocketAddress = new InetSocketAddress(node.getIp(), node.getPort());
            serverNode.setInetSocketAddress(inetSocketAddress);
            try {
                if (inetSocketAddress.getAddress().isReachable(1000)) {
                    //健康状态
                    serverNode.setHealth(true);
                } else {
                    //健康状态
                    serverNode.setHealth(false);
                }
            } catch (Exception e) {
                serverNode.setHealth(false);
            }
            //节点名字
            serverNode.setNodeDesc(node.getNodeDesc());
            //路由名字
            serverNode.setRouterDesc(node.getRouterDesc());
            //权重
            serverNode.setWeight(node.getWeight());
            //负载类型
            serverNode.setStrategyType(StrategyType.values()[node.getStrategyType() - 1]);
            manager.addServerNode(node.getRouterId(), serverNode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void addOrUpdateServerData(List<GatewayRouterNodeDTO> gatewayRouterNodeDTO) {
        Map<String, List<GatewayRouterNodeDTO>> collect = gatewayRouterNodeDTO.stream().collect(Collectors.groupingBy(GatewayRouterNodeDTO::getRouterId));
        collect.forEach((k, v) -> {
            if (manager.isExistServerNode(k)) {
                manager.removeServerNode(k);
            }
            for (GatewayRouterNodeDTO routerNodeDTO : v) {
                addServer(routerNodeDTO);
            }
        });
    }

    @Override
    public void removeServerData(String routerId) {
        manager.removeServerNode(routerId);
    }

    @Override
    public void initServerData() {
        List<GatewayRouterNodeDTO> all = gatewayRouterService.all();
        for (GatewayRouterNodeDTO node : all) {
            addServer(node);
        }
    }

    @Override
    public void restartServerData() {
        manager.clearAll();
        initServerData();
    }
}
